package com.qys.livesMall.shop.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.qys.livesMall.app.user.model.dto.sys.SysUserBalanceChangeDTO;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.model.enums.UserBalanceLogTypeEnum;
import com.qys.livesMall.app.user.model.enums.UserTypeEnum;
import com.qys.livesMall.app.user.service.IH2AppUserBalanceService;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.shop.constants.OrderStatus;
import com.qys.livesMall.shop.constants.PayMethod;
import com.qys.livesMall.shop.constants.ShopConstant;
import com.qys.livesMall.shop.dao.H2ShopBaseDao;
import com.qys.livesMall.shop.dao.ShopOrderSettlementDao;
import com.qys.livesMall.shop.enums.ShopBalanceTradeTypeEnum;
import com.qys.livesMall.shop.enums.ShopBusinessTypeEnum;
import com.qys.livesMall.shop.event.UserGradeIntegralOrderEvent;
import com.qys.livesMall.shop.event.pojo.UserGradeIntegralOrderPOJO;
import com.qys.livesMall.shop.modal.dto.settlement.SettlementHandleContext;
import com.qys.livesMall.shop.modal.dto.settlement.SuperiorInfo;
import com.qys.livesMall.shop.modal.dto.shop.balance.ShopBalanceHandle;
import com.qys.livesMall.shop.modal.entity.*;
import com.qys.livesMall.shop.modal.vo.H2ShopHierarchyIncomeConfigVO;
import com.qys.livesMall.shop.open.anchor.service.AnchorServer;
import com.qys.livesMall.shop.service.*;
import com.qys.livesMall.system.service.IH2SysConfigService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @menu ShopOrderSettlementServiceImpl
 * @date 2023/07/12 11:55
 */
@Slf4j
@Service
public class ShopOrderSettlementServiceImpl implements ShopOrderSettlementService {



    @Autowired
    private H2ShopBaseDao h2ShopBaseService;

    @Autowired
    private IH2SysConfigService sysConfigService;

    @Autowired
    private ShopOrderSkuService shopOrderSkuService;

    @Autowired
    private ShopIncomeConfigService incomeConfigService;

    @Autowired
    private H2ShopHierarchyIncomeConfigService shopHierarchyIncomeConfigService;

    @Autowired
    private ShopGoodsSkuStocksService shopGoodsSkuStocksService;

    @Autowired
    private IH2AppUserService ih2AppUserService;

    @Autowired
    private ShopOrderSettlementTX shopOrderSettlementTX;

    @Autowired
    private AnchorServer anchorServer;
    @Autowired
    private ShopOrderSettlementDao shopOrderSettlementDao;

    @Autowired
    private H2ShopLevelService shopLevelService;

    @Resource
    private ApplicationContext applicationContext;
    /**
     * 默认结算周期
     */
    private Integer defaultSettlementDay;

    /**
     * 默认分成配置
     */
    private ShopIncomeConfig incomeConfig=null;
    /**
     * 默认分成配置
     */
    private List<H2ShopHierarchyIncomeConfigVO> h2ShopHierarchyIncomeConfigs=null;

    private Integer getDefaultSettlementDay(){
        //获取默认周期配置
        if (defaultSettlementDay!=null){
            return defaultSettlementDay;
        }
        String da=sysConfigService.getConfigKey("shop_settlement_day");
        if (StringUtils.isBlank(da)){
            da="15";
        }
        Integer daInt=Integer.valueOf(da);
        defaultSettlementDay=daInt;
        return daInt;
    }

    private ShopIncomeConfig getIncomeConfig(){
        //获取分成配置
        if (incomeConfig!=null){
            return incomeConfig;
        }
        incomeConfig=incomeConfigService.get();
        return incomeConfig;

    }

    private ShopOrderPaymentRate getPlatformRatio(Integer id,ShopOrderPaymentRate rate){
        H2ShopLevel level=shopLevelService.getById(id);
        rate.setPlatformRate(level.getPlatformRatio());
        if (level==null||level.getPlatformRatio()==null){
           rate.setPlatformRate(new BigDecimal("0"));
        }
        if (level==null||level.getMinIncomeRatio()==null){
            level.setMinIncomeRatio(new BigDecimal("0"));
        }
        if (level==null||level.getMaxIncomeRatio()==null){
            level.setMaxIncomeRatio(new BigDecimal("0.05"));
        }
        double randomNum = level.getMinIncomeRatio().doubleValue() + Math.random() * (level.getMaxIncomeRatio().doubleValue()-level.getMinIncomeRatio().doubleValue());
        rate.setIncomeRate(new BigDecimal(String.valueOf(randomNum)).setScale(4,RoundingMode.HALF_DOWN));
        return rate;
    }

    private List<H2ShopHierarchyIncomeConfigVO> getH2ShopHierarchyIncomeConfigs(){
        if (h2ShopHierarchyIncomeConfigs!=null){
            return h2ShopHierarchyIncomeConfigs;
        }
        h2ShopHierarchyIncomeConfigs=shopHierarchyIncomeConfigService.listAll();
        if (h2ShopHierarchyIncomeConfigs==null){
            h2ShopHierarchyIncomeConfigs=new ArrayList<>();
        }
        return h2ShopHierarchyIncomeConfigs;
    }

    @Override
    public void settlement() {
        log.info("开始配置加载....");
        Integer daInt=getDefaultSettlementDay();
        getIncomeConfig();
        getH2ShopHierarchyIncomeConfigs();

        log.info("配置加载完成！");
        log.info("开始加载店铺....");
        //获取店铺
        List<H2ShopBase> shops= h2ShopBaseService.getAllShop();
        if (CollectionUtils.isEmpty(shops)){
            return;
        }
        log.info("共"+shops.size()+"个店铺加载完成！");
        //
        int i=1;
        for (H2ShopBase shop:shops){
            log.info("开始第"+i+"个店铺结算....");
            shopSettlement(shop,daInt);
            log.info("第"+i+"个店铺结算完成");
            i++;
        }
    }

    private void shopSettlement(H2ShopBase shop,Integer defaultDay){
        if (shop.getSettlementDay()!=null){
            defaultDay=shop.getSettlementDay();
        }
        SettlementHandleContext handle=new SettlementHandleContext();

        Date end= DateUtil.offsetDay(DateUtil.date(),-defaultDay);
        //获取订单
        List<ShopOrderSku> orders= shopOrderSkuService.getNoSettlementOrder(shop.getId(),end);
        if (CollectionUtils.isEmpty(orders)){
            log.info("店铺："+shop.getId()+"有0个订单结算");
            return;
        }
        //获取主播
        //List<Long> anchorIds= orders.stream().filter(o->o.getAnchorId()!=null).map(ShopOrderSku::getAnchorId).collect(Collectors.toList());

        //获取订单商品的进货单

        log.info("店铺："+shop.getId()+"有"+orders.size()+"个订单结算");
        //结算
        for(ShopOrderSku order:orders){

            try {
                ShopOrderSettlementInfo settlementInfo=shopOrderSettlementDao.getByOrderId(order.getId());
                if (settlementInfo==null){
                    settlementByOrder(order.getOrderId());
                    settlementInfo=shopOrderSettlementDao.getByOrderId(order.getId());
                    if(settlementInfo==null){
                        continue;
                    }
                }

                handle.setOrderSku(order);
                handle.setSettlementInfo(settlementInfo);
                List<SuperiorInfo> superiorInfos =JSON.parseArray(settlementInfo.getSuperiorProfitDetail(),SuperiorInfo.class);
                handle.setSuperiorInfos(superiorInfos);
                //转账
                shopOrderSettlementTX.handleTransferAccounts(handle);

                //直播的会员
                UserGradeIntegralOrderPOJO userGradeIntegralOrderPOJO=new UserGradeIntegralOrderPOJO();
                userGradeIntegralOrderPOJO.setUserId(Long.valueOf(order.getUserId()));
                userGradeIntegralOrderPOJO.setGradeIntegral(order.getMoney().multiply(new BigDecimal(100)));
                applicationContext.publishEvent(new UserGradeIntegralOrderEvent(userGradeIntegralOrderPOJO));
            }catch (Exception e){
                log.error("订单:"+order.getSkuOrderId()+"结算-转账失败"+e);
            }
        }
    }

    public void orderSettlement(SettlementHandleContext handle){
        ShopOrderSku order=handle.getOrderSku();
        ShopGoodsSkuStocks skuStocks=handle.getSkuStocks();
        //原总价
        BigDecimal totalAmount= skuStocks.getPrice().multiply(BigDecimal.valueOf(order.getNum()));
        //实际总价
        BigDecimal totalActualAmount= order.getPrice().multiply(BigDecimal.valueOf(order.getNum()));
        //成本价
        BigDecimal totalCostAmount=order.getCostPrice().multiply(BigDecimal.valueOf(order.getNum()));
        //总盈利
        BigDecimal totalProfit=totalActualAmount.multiply(handle.getPaymentRate().getIncomeRate());
        //店铺补贴收益
        BigDecimal shopSubsidyProfit=totalAmount.subtract(totalActualAmount);
        //平台盈利
        BigDecimal platformProfit=totalProfit.multiply(handle.getPaymentRate().getPlatformRate()).setScale(4,RoundingMode.DOWN);
        //主播盈利
        BigDecimal anchorProfit=new BigDecimal("0");
        if(handle.getAnchorUserId()!=null){
            anchorProfit=totalProfit.multiply(handle.getPaymentRate().getAnchorRate()).setScale(4,RoundingMode.DOWN);
        }
        //上级盈利
        BigDecimal totalSuperiorProfit=new BigDecimal("0");
        for(SuperiorInfo superiorInfo:handle.getSuperiorInfos()){
            superiorInfo.setProfit(totalProfit.multiply(superiorInfo.getDividendRatio()).setScale(4, RoundingMode.DOWN));
            totalSuperiorProfit=totalSuperiorProfit.add(superiorInfo.getProfit());
        }

        //店铺盈利
        BigDecimal shopProfit=totalProfit.subtract(platformProfit).subtract(anchorProfit).subtract(totalSuperiorProfit);
        //构建
        ShopOrderSettlementInfo settlementInfo=new ShopOrderSettlementInfo();
        settlementInfo.setShopId(order.getShopId());
        settlementInfo.setOrderId(order.getId());
        settlementInfo.setAnchorUserId(handle.getAnchorUserId());
        settlementInfo.setTotalAmount(totalAmount);
        settlementInfo.setTotalActualAmount(totalActualAmount);
        settlementInfo.setTotalCostAmount(totalCostAmount);
        settlementInfo.setTotalProfit(totalProfit);
        settlementInfo.setPlatformProfit(platformProfit);
        settlementInfo.setShopSubsidyProfit(shopSubsidyProfit);
        settlementInfo.setAnchorProfit(anchorProfit);
        settlementInfo.setSuperiorProfit(totalSuperiorProfit);
        settlementInfo.setShopProfit(shopProfit);
        settlementInfo.setStatus(0);
        settlementInfo.setSuperiorProfitDetail(JSONObject.toJSONString(handle.getSuperiorInfos()));
        settlementInfo.setPaymentRate(JSONObject.toJSONString(handle.getPaymentRate()));
        settlementInfo.setCreateDate(LocalDateTime.now());

        handle.setSettlementInfo(settlementInfo);
    }

    private void handleGoodsMoney(SettlementHandleContext handle){
        ShopGoodsSkuStocks skuStocks=handle.getSkuStocks();
        if (Objects.equals(skuStocks.getPayType(), Constants.YesNo.NO)){
            //先货后款
            handle.setDeductCost(true);
            handle.getSettlementInfo().setReturnCost(Constants.YesNoInt.YES);
        }else {
            handle.setDeductCost(false);
            handle.getSettlementInfo().setReturnCost(Constants.YesNoInt.NO);
        }
    }

    private ShopOrderPaymentRate buildDefaultRate(H2AppUser shopUser,List<SuperiorInfo> superiorInfos,Integer shopLevelId) {
        ShopOrderPaymentRate rate = new ShopOrderPaymentRate();
        rate.setSuperiorRate(new BigDecimal("0"));
        incomeConfig = getIncomeConfig();
        h2ShopHierarchyIncomeConfigs=getH2ShopHierarchyIncomeConfigs();
        //平台
        //获取店铺等级
        rate=getPlatformRatio(shopLevelId,rate);
        //主播
        rate.setAnchorRate(incomeConfig.getAnchor());

        Long superiorUserId = shopUser.getSuperior();
        //获取上级

        for (H2ShopHierarchyIncomeConfigVO hierarchy : h2ShopHierarchyIncomeConfigs) {
            if (superiorUserId == null) {
                continue;
            }
            H2AppUser superiorUser = null;

            superiorUser = ih2AppUserService.getById(String.valueOf(superiorUserId));
            if (superiorUser == null) {
                superiorUserId = null;
                continue;
            }
            //分成
            SuperiorInfo superiorInfo = new SuperiorInfo();
            superiorInfo.setUserId(superiorUser.getId());
            //不是店主 不分成
            if (!Objects.equals(UserTypeEnum.STORE.getCode(), superiorUser.getUserType())
                    && !Objects.equals(UserTypeEnum.STORE_AND_ANCHOR.getCode(), superiorUser.getUserType())) {
                superiorUserId = superiorUser.getSuperior();
                superiorInfo.setUserStatus(Constants.YesNoInt.NO);
                continue;
            }

            H2ShopBase superiorShop = h2ShopBaseService.getByUserId(Long.parseLong(superiorUser.getId()));
            //店铺不存在 不分成
            if (superiorShop == null) {
                superiorUserId = superiorUser.getSuperior();
                superiorInfo.setUserStatus(Constants.YesNoInt.NO);
                continue;
            }

            //店铺状态未营业 不分成
            if (!Objects.equals(superiorShop.getStatus(), ShopConstant.ShopStatus.IN_BUSINESS)) {
                superiorUserId = superiorUser.getSuperior();
                superiorInfo.setUserStatus(Constants.YesNoInt.NO);
                continue;
            }

            superiorUserId = superiorUser.getSuperior();
            superiorInfo.setShopId(superiorShop.getId());
            superiorInfo.setUserStatus(Constants.YesNoInt.YES);
            superiorInfo.setHierarchy(hierarchy.getHierarchy());
            superiorInfo.setName(hierarchy.getName());
            superiorInfo.setDividendRatio(hierarchy.getDividendRatio());
            superiorInfos.add(superiorInfo);

            rate.setSuperiorRate(rate.getSuperiorRate().add(superiorInfo.getDividendRatio()));
        }
        rate.setShopRate(new BigDecimal("1").subtract(rate.getPlatformRate()).subtract(rate.getAnchorRate()).subtract(rate.getSuperiorRate()));

        return rate;
    }

    private void buildAnchorRate(SettlementHandleContext handle,Map<Long,BigDecimal> anchorRateMap){
        if (handle.getOrderSku().getAnchorId()==null){
            return;
        }
        BigDecimal rate= anchorRateMap.get(handle.getOrderSku().getAnchorId());

        if (rate==null){
            //不结算
            handle.getPaymentRate().setAnchorRate(new BigDecimal("0"));
        }else if (rate.compareTo(new BigDecimal("0"))==0){
            //按默认比例结算 --前面已有默认，不再设置
        }else {
            //按主播设置结算
            handle.getPaymentRate().setAnchorRate(rate);
        }
        handle.getPaymentRate().setShopRate(new BigDecimal("1")
                .subtract(handle.getPaymentRate().getPlatformRate())
                .subtract(handle.getPaymentRate().getAnchorRate())
                .subtract(handle.getPaymentRate().getSuperiorRate()));

    }

    @Override
    public void settlementByOrder(Long mainOrderId){

        List<ShopOrderSku> orders= shopOrderSkuService.getByOrderId(mainOrderId);
        if (CollectionUtils.isEmpty(orders)){
            log.info("订单："+mainOrderId+"有0个sku结算");
            return;
        }
        Set<Long> stockIds=orders.stream().map(ShopOrderSku::getStocksId).collect(Collectors.toSet());
        List<ShopGoodsSkuStocks> skuStocks= shopGoodsSkuStocksService.listByIds(stockIds);
        Map<Long,ShopGoodsSkuStocks> skuStocksMap=skuStocks.stream().collect(Collectors.toMap(ShopGoodsSkuStocks::getId, v->v,(v1, v2)->v1));

        //获取主播
        List<Long> anchorIds= orders.stream().filter(o->o.getAnchorId()!=null).map(ShopOrderSku::getAnchorId).collect(Collectors.toList());
        Map<Long,BigDecimal> anchorRateMap=anchorServer.getAnchorCommissionRate(anchorIds);

        //按店铺分组
        Map<Long,List<ShopOrderSku>> orderMap=orders.stream().collect(Collectors.groupingBy(ShopOrderSku::getShopId));

        for(Long shopId:orderMap.keySet()){
            H2ShopBase shop=h2ShopBaseService.getById(shopId);

            //当前店主
            H2AppUser shopUser=ih2AppUserService.getById(String.valueOf(shop.getUserId()));

            //上级
            List<SuperiorInfo> superiorInfos = new ArrayList<>();
            ShopOrderPaymentRate rate=buildDefaultRate(shopUser,superiorInfos,shop.getShopLevelId());

            List<ShopOrderSku> orderSkus=orderMap.get(shopId);
            for(ShopOrderSku orderSku:orderSkus){
                SettlementHandleContext handle=new SettlementHandleContext();
                handle.setShopUser(shopUser);
                handle.setOrderSku(orderSku);
                //加载默认店铺配置
                handle.setSuperiorInfos(superiorInfos);
                handle.setPaymentRate(rate);
                //加载主播配置
                Long anUserId=anchorServer.getAnchorUserId(orderSku.getAnchorId());
                if (anUserId!=null){
                    handle.setAnchorUserId(anUserId);
                }
                buildAnchorRate(handle,anchorRateMap);

                handle.setSkuStocks(skuStocksMap.get(orderSku.getStocksId()));
                //计算分成
                orderSettlement(handle);
                //货款
                handleGoodsMoney(handle);
                shopOrderSettlementTX.saveShopOrderSettlementInfo(handle.getSettlementInfo());
            }

        }

    }

}

